/**
 * actions : 是store提供的带回调模式的事件接口，一般非即时操作的代码写在这里,即采用异步方式
 *          可以在组件中用mapActions混合到methods中
 *          - 常规调用方式是this.$store.dispatch('actionName',arg);
 *          - 用dispatch方式，可以理解成像 消息接口，发出一个消息将触发一系列异步的操作
 */
import _ from 'lodash'
/* eslint-disable */

export function JOIN_ROOM ({ state,commit,getters },{ roomName,userName,portrait }) {
    return new Promise((resolve,reject)=>{
        if(!getters.socket) 
            reject({info:"socket is unconnencted."});
        else
            getters.socket.emit('JOIN_ROOM',{roomName,userName,portrait:'/rcn/mm/'+getters.backMM+'.jpg?thumb=1'},(err,res)=>{
                console.log(err,res)
                if(err) reject(err)
                else {
                    commit('ROOM_STATES',res);
                    resolve(res);
                }
            });
    });
}

export function SOCKET_EMIT({ getters },[ event,message,callback ]){
    if(!getters.socket) return;
    getters.socket.emit(event,message,callback);
}
//每个消息尽量只Listen一次
//listens : { 'EventName' : callbackFunction ,...}
export function SOCKET_LISTENER({ getters },listens) {
    if(!getters.socket) return;
    _.each(listens,(callback,eventName)=>{
        getters.socket.on(eventName,callback);
    })
}

//启动麦克风和摄像头
export function CONTROL_LOCAL_CAMERA ({commit,getters}) {
    return new Promise((resolve,reject)=>{
        if(getters.cameraVideoStream){
            getters.cameraVideoStream.getTracks().forEach(function(track) {
                track.stop();
            });
            
            _.each(getters.friends,f=>{
                if(f.ping) f.ping.removeStream(getters.cameraVideoStream);
            })
            commit('CAMERA_VIDEO',{stream:null});
            resolve();
        }else
        navigator.mediaDevices.getUserMedia({ audio:true,video:{ facingMode: "user" }}) //{ audio:true,video:{ mediaSource:'screen' }}
        .then(stream=>{
            //存储视频
            commit('CAMERA_VIDEO',{stream});
            //默认打开自己的muted视频
            commit('DISPALY_VIDEO',{stream:getters.mutedStream});
            resolve(stream);
        }).catch(err=>{
            reject(err);
        });
    });
}
//启动桌面共享
export function CONTROL_LOCAL_SCREEN ({commit,getters}) {
    return new Promise((resolve,reject) => {
        if(getters.screenVideStream){
            getters.screenVideStream.getTracks().forEach(t=>t.stop());
            _.each(getters.friends,f=>{
                if(f.ping) f.ping.removeStream(getters.screenVideStream);
            })
            commit('SCREEN_VIDEO',{stream:null});
            resolve();
        }else
        navigator.mediaDevices.getUserMedia({ audio:true,video:{ mediaSource:'screen' }})
        .then(stream=>{
            commit('SCREEN_VIDEO',{stream});
            commit('DISPALY_VIDEO',{stream:getter.mutedStream});
            resolve(stream);
        }).catch(err=>{
            reject(err);
        });
    });
}

//跟朋友建立RTC连接,将videoStream分享给他
export function OFFER_2_FRIEND({getters,commit},{name}){
    //创建offer之前必须将想要分享的stream添加到peer中
    //所有必须要先有视频
    if(!getters.cameraVideoStream) return;
    var peer = new RTCPeerConnection(getters.RTCConfig);
    //当ice服务器验证通过时,将验证内容同步给朋友,**我的ping对对方来讲就是pong,所以type是pong**
    peer.onicecandidate = (event)=>{
        if (event.candidate) {
            console.log('get offer ICE:',event);
            getters.socket.emit('ICE',{to:name,type:'pong',ice: event.candidate});
        } else {
            console.log("End of candidates");
        }
    };
    //否则offer无法创建成功(主要是firefox)
    peer.addStream(getters.cameraVideoStream);
    //创建一个offer
    peer.createOffer()
    .then((dsp)=>{
        peer.setLocalDescription(dsp);
        //通过socket发送给朋友
        commit('FRIEND_PING',{ name, peer });
        getters.socket.emit('OFFER',{to:name,dsp:dsp});
    })
    .catch((err)=>{
        console.log(err);
    });
}
export function ANSWER_FROM_FRIEND ({ getters },{ name, dsp }){
    var friend = _.find(getters.friends,{ name });
    if(!friend || !friend.ping) return;
    friend.ping.setRemoteDescription(dsp);
}
export function ICE_FROM_FRIEND ({ getters },{ name, type, ice }){
    var friend = _.find(getters.friends,{ name });
    if(!friend || !friend[type]) return;
    friend[type].addIceCandidate(ice)
    .then(
      ()=>console.log('add ',type,' ice.'),
      (err)=>console.log(err)
    );
}
//给发来offer的朋友一个answer
export function ANSWER_2_FRIEND ({ getters, commit },{ name,dsp }){
    var peer = new RTCPeerConnection(getters.RTCConfig);
    //当ice服务器验证通过时,将验证内容同步回朋友,**我的pong对对方来讲就是ping,所以type是ping**
    peer.onicecandidate = (event)=>{
        if (event.candidate) {
            console.log('get answer ICE:',event);
            getters.socket.emit('ICE',{to:name,type:'ping',ice: event.candidate});
        } else {
            console.log("End of candidates");
        }
    };
    //当收到对方的stream
    peer.onaddstream = ({ stream })=>{
        commit('FRIEND_STREAM',{ name, stream });
        commit('DISPALY_VIDEO',{stream});
    };
    //关闭连接时
    // peer.onsignalingstatechange = (sts) => {
    //     console.log('friend ',name,'pong status ',sts);
    //     if(sts == 'closed'){
    //         commit('FRIEND_STREAM',{ name, stream:null });
    //     }
    // }
    //
    peer.onremovestream = (stream) => {
        console.log('friend ',name,'pong remove stream ',stream);
        commit('FRIEND_STREAM',{ name, stream:null });
    }
    peer.setRemoteDescription(dsp);
    //创建一个Answer
    peer.createAnswer()
    .then((dsp)=>{
        peer.setLocalDescription(dsp);
        //通过socket发送给朋友
        getters.socket.emit('ANSWER',{to:name,dsp:dsp});
        commit('FRIEND_PONG',{ name, peer})
    });
}
//向所有朋友发出offer
export function OFFER_2_ALL({ getters,dispatch }) {
    var friends = getters.friends;
    friends.forEach(f=>{
        dispatch('OFFER_2_FRIEND',f);
    })
}